﻿#I @"C:\Users\Johan\Desktop\WingBeats\bin\Debug"
#I @"C:\Users\joel.mueller\Documents\Visual Studio 2010\Projects\WingBeats\bin\Debug"
#r "WingBeats"
#r "WingBeats.Xhtml"

open WingBeats.Xhtml
open WingBeats.Xml

let e = XhtmlElement()

// An idea of a pattern to use. Why not pass a Create and a Transform method along with data.
// This way we can create super flexible controls/patterns.

type LinkType = 
    { Name      : string
      Url       : string 
      Selected  : bool
      Transform : option<(Node * LinkType) -> Node>
      Create    : LinkType -> Node }

let defaultLink = 
    { Name        = ""
      Url         = ""
      Selected    = false
      Transform   = None
      Create      = 
        fun l ->
            e.Li (if l.Selected then [ "class", "selected" ] else [])
                 [ e.A ["href", l.Url]
                       [ e.Str l.Name ] 
                 ]
    }

let menu (links : #seq<LinkType>) =
    if (Seq.length links) > 0
        then
            e.Ul ".menu"
                (seq {
                    for l in links do
                        let link = l.Create l
                        match l.Transform with
                        | Some transform -> yield ((link, l) |> transform)
                        | None -> yield link    
                })
        else 
            NoNode

type TemplateContent = { Title         : string
                         Language      : string
                         PageLayout    : TemplateContent -> Node
                         HeadLayout    : TemplateContent -> Node
                         HeadContent   : TemplateContent -> Node list
                         BodyLayout    : TemplateContent -> Node
                         HeaderLayout  : TemplateContent -> Node
                         HeaderContent : TemplateContent -> Node list
                         MainLayout    : TemplateContent -> Node
                         MainContent   : TemplateContent -> Node list
                         FooterLayout  : TemplateContent -> Node
                         FooterContent : TemplateContent -> Node list
                       }
                       with member this.ToNode () = this |> this.PageLayout

let noNodeIfEmpty contentLayout containerLayout (c : TemplateContent) = 
    let (content : Node list) = c |> contentLayout
    if content = []
        then NoNode
        else content |> containerLayout

let defaultPage : TemplateContent = 
    { Title         = "Title not set"
      Language      = "en"
      PageLayout    = fun c -> e.Html [ ("lang", c.Language); ("xml-lang", c.Language) ] // xml:lang raises an exception 
                                      [ c |> c.HeadLayout; c |> c.BodyLayout ]
      HeadLayout    = fun c -> 
                        e.Head (seq { yield e.Title [ e.Str c.Title ]
                                      for n in (c |> c.HeadContent) -> n })
      HeadContent   = fun c -> []
      BodyLayout    = fun c -> e.Body [ e.Div "#page" [ c |> c.HeaderLayout
                                                        c |> c.MainLayout
                                                        c |> c.FooterLayout ]
                                      ]
      HeaderLayout  = fun c ->
                        c |> noNodeIfEmpty (c.HeaderContent)
                                           (e.Div "#header")
      HeaderContent = fun c -> []
      MainLayout    = fun c ->
                        c |> noNodeIfEmpty (c.MainContent)
                                           (e.Div "#main-content")
      MainContent   = fun c -> []
      FooterLayout  = fun c ->
                        c |> noNodeIfEmpty (c.FooterContent)
                                           (e.Div "#footer")
      FooterContent = fun c -> []
    }

type Patterns () =
    let e = XhtmlElement()
    member this.StyleSheet (url) =
        e.Link [ ("rel", "stylesheet"); ("type", "text/css"); ("href", url) ]
    member this.JavaScriptFile (url) =
        e.Script [ ("type", "text/javascript"); ("language", "JavaScript"); ("src", url) ] []